home *** CD-ROM | disk | FTP | other *** search
- page 66, 132
- title Binary (bit) oriented STR and VAL for BASIC7 / QBX
- subttl By Jim Mack, Editing Services Co.
-
- odg equ <offset dgroup>
-
- comment |
-
- Updated 7/28/90 for BC7 and QBX
- ==============================================================================
- THIS VERSION IS ONLY FOR BC7.x AND QBX
- ==============================================================================
-
- Implements routines to generate and interpret binary strings.
-
- Two procedures are declared in BASIC:
-
- DECLARE FUNCTION BitStr$ (word%)
- DECLARE FUNCTION BitVal& (ones$) 'or BitVal% (ones$)
-
- BitStr returns a 16-byte string in the form "0010010000111001"
- with 1's corresponding to set bits in WORD%
-
- BitVal returns the value of a string such as the one above. Only the
- first 16 places in the string are evaluated. Fewer may be used.
- A null string returns a zero result.
-
- NOTE: BitVal can be declared as an integer function instead, since
- the entire value is returned in the lower 16 bits. If you use it
- that way, returned vales are signed integers: a string whose highest
- bit is set will return a negative value. As a long integer function,
- values are always positive.
-
- | comment ends
-
- page+
- EXTRN StringAssign:FAR ; in the BC/QBX runtime
- EXTRN StringAddress:FAR
- EXTRN StringLength:FAR
-
- .model medium, basic
- page+
- .data
-
- ; This is a string descriptor and associated string body for our use
-
- StrDesc dd 0 ; this is a valid QBX string descriptor...
-
- StrText db 16 dup (0) ; our local string
-
- .code
-
- BitStr PROC uses di, vlu
-
- cld
- mov ax, ds
- mov es, ax ; this so "stosb" will work for sure
- assume es:@data
- mov bx, vlu
- mov dx, [bx] ; dx = word containing bits to test
- mov cx, 16 ; number of bit positions
- mov di, odg:StrText ; point to beginning of our own string
- mov ah, '0'
- @@: mov al, ah ; for each bit, start with "0"
- shl dx, 1 ; shift a bit into carry
- adc al, 0 ; makes "0" into "1" if bit is set
- stosb ; put "0" or "1" into string
- loop @b ; until all 16 bits tested
- push ds ; push segment and offset to...
- mov ax, odg:StrText ; ...our string text
- push ax
- mov ax, 16
- push ax ; indicate length of our string
- push ds
- mov ax, odg:StrDesc
- push ax ; pass seg+ofs of our descriptor
- xor ax, ax
- push ax ; pass a zero to indicate VL string
- call StringAssign ; move our string into BASIC's
- mov ax, odg:StrDesc ; pointer to our own descriptor
- ret
-
- BitStr ENDP
- page+
- BitVal PROC uses di si, str
-
- ; The value is taken in two steps: first, the passed string is right-
- ; justified (RSET) into a local string accumulator of exactly 16 bytes,
- ; with ASCII bias removed. Then the local string is evaluated to a
- ; numeric result. This allows strings of fewer than 16 bytes to be
- ; aligned correctly, and illegal values to be detected easily.
-
- cld
- push str
- call StringLength ; get length the BC7 way
- or ax, ax
- jz bv99 ; null string passed, exit with zero
- push ax ; hold length of source string
- mov ax, ds
- mov es, ax ; point ES to DGROUP
- mov di, odg:StrText ; will end up pointing off the end
- mov cx, 8
- xor ax, ax
- rep stosw ; zero our string accumulator
- push str
- call StringAddress ; get segmented address the BC7 way
- mov si, ax ; far address comes back in DX:AX
- mov ds, dx ; address of source now in DS:SI
- assume ds:nothing
- pop cx ; recover saved length
- cmp cx, 16 ; if < 16, use passed length
- jna @f
- mov cx, 16 ; maximum string is 16 characters
- @@: add si, cx
- std ; work backwards...
- dec si ; ...from ends of strings...
- dec di ; ...to right-align the data
- xor bx, bx ; clear numeric accumulator
- @@: lodsb ; get string byte
- cmp al, '1' ; abort on illegal characters
- ja bv90
- cmp al, '0'
- jb bv90
- and al, 1 ; remove ASCII bias
- stosb ; put into string accumulator
- loop @b
- cld ; string accumulator now full
- mov ax, @data
- mov ds, ax ; reset DS to DGROUP
- assume ds:@data
- mov si, odg:StrText ; point DS:SI to our string accum.
- mov cx, 16
- @@: ; turn string into numeric equivalent
- lodsb
- xor ah, ah ; clear AH and clear carry
- sub ah, al ; set carry for rotate if '1'
- rcl bx, 1 ; set bit in result
- loop @b ; repeat until string empty
- bv90:
- mov ax, bx ; accumulator to result
- bv99:
- xor dx, dx ; make valid for INT or LONG
- cld ; clean up flags or die later
- ret
-
- BitVal ENDP
-
- END
-
-